package fons.model.ontology;

import java.util.List;
import java.util.Map;

import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import fons.model.ontology.language.AbstractNamed;
import fons.model.query.fun.Function;
import fons.model.query.fun.ReferenceFun;
import fons.model.query.fun.Scope;

public class Metric extends AbstractNamed {
	private final List<ReferenceFun> arguments = Lists.newArrayList();
	private final Map<ReferenceFun, String> dynamicArguments = Maps.newHashMap();
	
	private Function function;

	public Metric(String name) {
		super(name);
	}

	public Metric addArgument (ReferenceFun argument) {
		arguments.add(argument);
		return this;
	}

	public Metric setFunction (Function function) {
		this.function = function;
		return this;
	}

	public void setScope (Scope scope) {
		for (ReferenceFun ref: arguments) {
			ref.setScope(scope);
		}
	}

	public Function apply() {
		return function.apply();
	}

	public List<ReferenceFun> getUnboundArguments() {
		List<ReferenceFun> result = Lists.newArrayList(
				Iterables.filter(arguments, new com.google.common.base.Predicate<ReferenceFun>() {
					@Override
					public boolean apply(ReferenceFun input) {
						return !input.isBound();
					}
				}));
		return result;
	}
	
	public String getTypeOf (ReferenceFun ref) {
		return dynamicArguments.get(ref);
	}

	@Override
	public String toString() {
		return getName();
	}

	public Metric addDynamicArgument(ReferenceFun ref, String type) {
		arguments.add(ref);
		dynamicArguments.put(ref, type);
		return this;
	}

	public Function getFunction() {
		return this.function;
	}
}
